import { spawn, spawnSync } from "child_process";
import { existsSync, readFileSync, writeFileSync } from "fs";
import path, { resolve } from 'path';
import PackUtil from "../utils/PackUtil";
import { BasePlatform } from "./BasePlatform";
import { ChannelInfo } from "./PlatformConfig";
import * as fs from 'fs';
import iconv from 'iconv-lite';

export class UnityAndroid extends BasePlatform {
    public isBundle: boolean = false;
    public bmsVersion: string = "";
    public bmsName: string = "";
    private _androidDir: string = "";

    public async beforeStartBuild() {
        console.log("Starting beforeStartBuild for UnityAndroid...");
        await super.beforeStartBuild();
        console.log("Completed beforeStartBuild for UnityAndroid.");
    }

    public async buildUnity(): Promise<boolean> {
        return new Promise<boolean>((resolve, reject) => {
            // resolve(true);
            // return;

            try {

                // 添加日志文件路径
                const logPath = path.join(this.projectDir, "UnityBuild.log");
                // unity 打包参数
                const unityArgs = [
                    '-quit',
                    '-batchmode',
                    '-projectPath',
                    `"${this.projectDir}"`,
                    '-executeMethod',
                    'CommandLineBuild.Main',
                    '-nographics',
                ];

                // 定义额外参数
                const extraArgs = [
                    '-bmsVersion',
                    this.version,
                    '-androidProjectPath',
                    this.outputPath,
                    '-bundle',
                    this.isBundle ? "true" : "false"
                ];
                // 合并参数
                const buildArgs = [...unityArgs, ...extraArgs];

                console.log("项目路径:", this.projectDir);
                console.log("引擎路径:", this.unityEnginePath);
                console.log("构建参数:", JSON.stringify(buildArgs, null, 2));
                console.log("日志路径:", logPath);

                let sp = spawn(this.unityEnginePath, buildArgs, {
                    shell: true,
                    windowsVerbatimArguments: true
                });

                let outputData = '';
                let errorData = '';

                sp.stdout.setEncoding('utf8');
                sp.stdout.on('data', (data) => {
                    outputData += data;
                    console.log("Unity Output:", data.toString());
                });

                sp.stderr.on('data', (data) => {
                    errorData += data;
                    console.error("Unity Error:", data.toString());
                });

                sp.on('error', (err) => {
                    console.error("Spawn Error:", err);
                    reject(err);
                });

                sp.on('exit', async (code, signal) => {
                    console.log(`\n=== Unity Build Process Completed ===`);
                    console.log(`Exit Code: ${code}, Signal: ${signal}`);

                    // 读取日志文件
                    try {
                        if (fs.existsSync(logPath)) {
                            const logContent = fs.readFileSync(logPath, 'utf8');
                            console.log("\n=== Unity Build Log ===");
                            console.log(logContent);
                        } else {
                            console.log("No build log file found at:", logPath);
                        }
                    } catch (error) {
                        console.error("Error reading log file:", error);
                    }

                    if (code === 0) {
                        console.log(`Build successful for channel: ${this.curPackChannel}`);
                        resolve(true);
                    } else {
                        console.error("\n=== Build Error Details ===");
                        console.error("Standard Output:", outputData);
                        console.error("Error Output:", errorData);
                        reject(new Error(`Unity build failed with code ${code}. Check the log for details.`));
                    }
                });

            } catch (error) {
                console.error(`\n=== Unity Build Failed ===`);
                console.error("Error:", error);
                reject(error);
            }
        });
    }

    private async initGradleWrapper() {
        try {
            const gradlewPath = process.platform === 'win32'
                ? path.join(this._androidDir, 'gradlew.bat')
                : path.join(this._androidDir, 'gradlew');

            // 如果不存在gradlew，则初始化
            if (!fs.existsSync(gradlewPath)) {
                console.log('Gradle Wrapper不存在，开始初始化...');

                // 使用gradle wrapper命令初始化
                const gradleHome = process.env.GRADLE_HOME;
                if (!gradleHome) {
                    throw new Error('未找到GRADLE_HOME环境变量，请确保已安装Gradle');
                }

                const gradleCmd = process.platform === 'win32' ? 'gradle.bat' : 'gradle';
                const gradleBin = path.join(gradleHome, 'bin', gradleCmd);

                if (!fs.existsSync(gradleBin)) {
                    throw new Error(`未找到Gradle执行文件: ${gradleBin}`);
                }

                // 执行gradle wrapper命令
                const result = await new Promise((resolve, reject) => {
                    const process = spawn(gradleBin, ['wrapper'], {
                        cwd: this._androidDir,
                        stdio: 'pipe',
                        shell: true
                    });

                    // 设置编码
                    process.stdout?.setEncoding('utf8');
                    process.stderr?.setEncoding('utf8');
                    // 收集输出信息
                    let stdoutData = '';
                    let stderrData = '';
                    // 标准输出
                    process.stdout?.on('data', (data) => {
                        stdoutData += data;
                        console.log(`Gradle wrapper 输出: ${data}`);
                    });
                    // 错误输出
                    process.stderr?.on('data', (data) => {
                        stderrData += data;
                        console.error(`Gradle wrapper 错误: ${data}`);
                    });
                    // 错误处理
                    process.on('error', (error) => {
                        console.error('Gradle wrapper 进程错误:', error);
                        reject(error);
                    });
                    // 进程结束
                    process.on('close', (code) => {
                        if (code === 0) {
                            resolve(true);
                        } else {
                            const error = new Error(
                                `Gradle wrapper 初始化失败:\n` +
                                `退出码: ${code}\n` +
                                `标准输出: ${stdoutData}\n` +
                                `错误输出: ${stderrData}`
                            );
                            reject(error);
                        }
                    });
                });

                console.log('Gradle Wrapper初始化完成');
            }

            // 设置执行权限（在非Windows系统上）
            if (process.platform !== 'win32') {
                fs.chmodSync(path.join(this._androidDir, 'gradlew'), '755');
            }

            return true;
        } catch (error) {
            console.error('初始化Gradle Wrapper失败:', error);
            throw error;
        }
    }

    //更新gradle-wrapper.properties 文件
    private async updateGradleWrapper(): Promise<void> {
        try {
            if (this.configData.nkdPath && this.configData.sdkPath) {
                const localPropertiesPath = path.join(this._androidDir, 'local.properties');
                if (!fs.existsSync(localPropertiesPath)) {
                    throw new Error(`找不到localPropertiesPath\n: ${localPropertiesPath}`);
                }

                const newLocalContent =
                    `ndk.dir=${this.configData.nkdPath.replace(/\\/g, '\\\\')}
                     sdk.dir=${this.configData.sdkPath.replace(/\\/g, '\\\\')}`;
                // 写入新配置
                fs.writeFileSync(localPropertiesPath, newLocalContent, 'utf8');
            }

            // 由于会先使用AndroidStudio中的gradle，所以需要先重写gradle-wrapper.properties，再执行gradlew wrapper 生成或更新
            if (this.configData.gradleVersion) {
                const wrapperPath = path.join(this._androidDir, 'gradle/wrapper/gradle-wrapper.properties');
                if (!fs.existsSync(wrapperPath)) {
                    throw new Error(`找不到gradle-wrapper.properties: ${wrapperPath}`);
                }

                // 从配置中获取Gradle版本
                const gradleVersion = this.configData.gradleVersion;
                console.log("gradleVersion:", gradleVersion);

                // 腾讯云镜像地址
                const tencentDistributionUrl = `distributionUrl=https\\://mirrors.cloud.tencent.com/gradle/gradle-${gradleVersion}-bin.zip`;
                const tencentGradleUrl = `https://mirrors.cloud.tencent.com/gradle/gradle-${gradleVersion}-bin.zip`;
                // 阿里云镜像地址
                const aliDistributionUrl = `distributionUrl=https\://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.7-bin.zip`;
                const aliGradleUrl = `https://mirrors.aliyun.com/macports/distfiles/gradle/gradle-${gradleVersion}-bin.zip`;

                const realDistributionUrl = aliDistributionUrl;
                const realGradleUrl = aliGradleUrl;

                fs.writeFileSync(wrapperPath, realDistributionUrl, 'utf8');
                console.log(`重写gradle-wrapper.properties: ${gradleVersion}`);

                // 设置环境变量，强制使用腾讯云镜像
                const env = {
                    ...process.env,
                    GRADLE_DISTRIBUTION_URL: realGradleUrl,
                    GRADLE_OPTS: '-Dorg.gradle.internal.http.connectionTimeout=1800000 -Dorg.gradle.internal.http.socketTimeout=1800000'
                };

                const gradleCmd = process.platform === 'win32' ? 'gradlew.bat' : './gradlew';
                const wrapperArgs = [
                    'wrapper',
                    `--gradle-version ${gradleVersion}`,
                    '--distribution-type', 'bin',
                    '--stacktrace',
                    // 直接指定下载地址
                    `--gradle-distribution-url=${realGradleUrl}`
                ];

                console.log('执行命令:', `${gradleCmd} ${wrapperArgs.join(' ')}`);
                console.log('使用镜像源:', env.GRADLE_DISTRIBUTION_URL);

                return new Promise((resolve, reject) => {
                    const wrapperProcess = spawn(gradleCmd, wrapperArgs, {
                        cwd: this._androidDir,
                        stdio: 'pipe',
                        shell: true,
                        env: env
                    });
                    wrapperProcess.stdout?.on('data', (data) => {
                        console.log(data.toString());
                    });
                    wrapperProcess.stderr?.on('data', (data) => {
                        console.error(data.toString());
                    });
                    wrapperProcess.on('close', (code) => {
                        if (code === 0) {
                            // 再次确认gradle-wrapper.properties的内容
                            const finalContent = fs.readFileSync(wrapperPath, 'utf8');
                            console.log('最终的gradle-wrapper.properties内容:', finalContent);

                            // 如果内容被改回默认地址，再次写入我们的地址
                            if (finalContent.includes('services.gradle.org')) {
                                const newContent = `distributionUrl=https\\://mirrors.cloud.tencent.com/gradle/gradle-${gradleVersion}-bin.zip`;
                                fs.writeFileSync(wrapperPath, newContent, 'utf8');
                                console.log('重新写入镜像源地址');
                            }

                            console.log(`成功更新Gradle Wrapper版本为: ${gradleVersion}`);
                            resolve();
                        } else {
                            const error = new Error(`更新Gradle Wrapper失败，退出码: ${code}`);
                            reject(error);
                        }
                    });
                    wrapperProcess.on('error', (err) => {
                        reject(err);
                    });
                });
            }

        } catch (error) {
            console.error('更新Gradle Wrapper失败:', error);
            throw error;
        }
    }

    private async syncGradleProject(): Promise<void> {
        try {
            console.log('开始同步Gradle配置和依赖...');
            const gradleCmd = process.platform === 'win32' ? 'gradlew.bat' : './gradlew';

            // 同步项目配置和依赖的命令
            const syncArgs = [
                'dependencies',           // 解析依赖
                '--refresh-dependencies', // 强制刷新依赖
                '--stacktrace'           // 显示详细错误信息
            ];

            const syncProcess = spawn(gradleCmd, syncArgs, {
                cwd: this._androidDir,
                stdio: 'pipe',
                shell: true
            });

            return new Promise<void>((resolve, reject) => {
                let output = '';
                let errorOutput = '';

                syncProcess.stdout.on('data', (data) => {
                    output += data;
                    console.log(data.toString());
                });

                syncProcess.stderr.on('data', (data) => {
                    errorOutput += data;
                    console.error(data.toString());
                });

                syncProcess.on('error', (error) => {
                    console.error('Gradle同步进程错误:', error);
                    reject(error);
                });

                syncProcess.on('close', (code) => {
                    if (code === 0) {
                        console.log('Gradle配置和依赖同步完成');
                        resolve();
                    } else {
                        console.error('同步过程输出:', output);
                        console.error('同步错误输出:', errorOutput);
                        reject(new Error(`Gradle同步失败，退出码: ${code}`));
                    }
                });
            });

        } catch (error) {
            console.error('Gradle同步失败:', error);
            throw error;
        }
    }

    private async handleSDKFileReplace(): Promise<void> {
        try {
            //@ts-ignore
            const replaceFilePath = global.extraParam?.split(',')
                .find((item: string) => item.startsWith('Extra_ReplaceFilePath='))
                ?.split('=')[1];

            if (!replaceFilePath) {
                console.log('没有需要替换的文件');
                return;
            }
            if (!fs.existsSync(replaceFilePath)) {
                console.warn(`替换文件不存在: ${replaceFilePath}`);
                return;
            }
            // 确定目标路径
            const fileName = path.basename(replaceFilePath);
            // 修改目标路径
            const targetPath = path.join(this._androidDir, 'unityLibrary', 'src', 'main', 'assets', fileName);
            console.log("replaceFilePath: ", replaceFilePath);
            // 复制文件到安卓工程目录
            fs.copyFileSync(replaceFilePath, targetPath);
            console.log(`成功复制替换文件到: ${targetPath}`);
        } catch (error) {
            console.error('处理替换文件失败:', error);
            throw error;
        }
    }

    public async afterBuildFinish(): Promise<void> {
        try {
            // 检查Android工程目录
            this._androidDir = this.outputPath;
            if (!fs.existsSync(this._androidDir)) {
                throw new Error(`Android工程目录不存在: ${this._androidDir}`);
            }

            //为了处理apk一些输出问题，删除outputs下所有东西
            const outputApkPath = path.join(this._androidDir, 'launcher', 'build', "outputs");
            if (existsSync(outputApkPath)) {
                PackUtil.removeFiles(outputApkPath);
            }

            // // 检查 build.gradle 中的版本信息
            // const launcherBuildGradlePath = path.join(this._androidDir, 'launcher/build.gradle');
            // if (fs.existsSync(launcherBuildGradlePath)) {
            //     const content = fs.readFileSync(launcherBuildGradlePath, 'utf8');
            //     const versionName = content.match(/versionName\s*['"](.*?)['"]/)?.[1];
            //     if (versionName !== this.version) {
            //         throw new Error(`版本号不一致,当前版本号:${versionName},期望版本号:${this.version}`);
            //     }
            // }


            // 初始化Gradle Wrapper
            await this.initGradleWrapper();
            await this.updateGradleWrapper();
            await this.syncGradleProject();
            // 处理替换文件
            await this.handleSDKFileReplace();

            console.log('开始执行Gradle构建...');
            console.log('工作目录:', this._androidDir);

            if (this.isBundle) {
                console.log('开始构建 APK...');
                await this.executeGradleTask('assembleRelease');
                console.log('APK 构建完成');

                console.log('开始构建 AAB...');
                await this.executeGradleTask('bundleRelease');
                console.log('AAB 构建完成');
            } else {
                // 仅构建 APK
                await this.executeGradleTask('assembleRelease');
            }

            this.logGradleConfig();
        } catch (error) {
            console.error('afterBuildFinish失败:', error);
            this.logGradleConfig();
            throw error;
        }
    }

    private async executeGradleTask(taskName: string): Promise<void> {
        const gradleCmd = process.platform === 'win32' ? 'gradlew.bat' : './gradlew';
        let gradleArgs = ["-q", taskName];
        let outputapks = "";

        // 添加其他参数
        if (this.configData.apksOutput) {
            // 根据任务名称判断构建类型
            let fileName = taskName === 'bundleRelease' ? 'Aab' : 'Apk';
            //@ts-ignore
            if (global.isUseReplaceVer) {
                fileName = 'Apk9.9.9';
            }

            /**
             * 构建完整的输出路径
             * Extra_SecFileName 为旧的，不删是为了兼容其他的打包机，
             * Extra_ReplaceVersion 为新的，格式为：1.1.0,1000,GP
             */
            let secFileName = "";

            //@ts-ignore
            secFileName = global.extraParam.split(',')
                .find((item: string) => item.startsWith('Extra_SecFileName='))
                ?.split('=')[1] || '';

            //@ts-ignore
            const replaceVersion = global.extraParam?.split(',')
                .find((item: string) => item.startsWith('Extra_ReplaceVersion='))
                ?.split('=')[1];
            if (replaceVersion?.split(' ')[2]) {
                secFileName = replaceVersion?.split(' ')[2];
            }


            outputapks = path.join(
                this.configData.apksOutput,
                `${fileName}${( fileName === 'Apk9.9.9' && secFileName != "") ? `/${secFileName}` : ""}`
            );

            // 检查并创建输出目录
            if (!fs.existsSync(outputapks)) {
                console.log(`创建输出目录: ${outputapks}`);
                fs.mkdirSync(outputapks, { recursive: true }); // recursive: true 会创建所有必需的父目录
            }

            this.outputPath = outputapks;
            gradleArgs.push(`-POUT_PUT_DIR=${outputapks}`);
        }

        // 跳过导出流程，使用指定的VersionCode 和 VersionName
        //@ts-ignore
        if (global.isUseReplaceVer) {
            //@ts-ignore
            const replaceVersion = global.extraParam?.split(',')
                .find((item: string) => item.startsWith('Extra_ReplaceVersion='))
                ?.split('=')[1];

            if (replaceVersion) {
                const replaceInfo = replaceVersion.split(' ');
                const newName = replaceInfo[0];
                const newCode = replaceInfo[1];
                // 防止修改了素材包版本号，导致版本号没有正确设置
                gradleArgs.push(`-PVERSION_CODE=${newCode}`);
                gradleArgs.push(`-PVERSION_NAME=${newName}`);
                console.log('更换了 Version 信息：', replaceVersion, " ,", newName, " ,", newCode);
            }
            else {
                console.log('没有更换 Version 信息');
            }
        }

        let keyStoreInfo = this.configData.keyStoreInfo;
        gradleArgs.push(
            `--stacktrace --info`,
            `-Pandroid.injected.signing.store.file=${keyStoreInfo.keystorePath || ''}`,
            `-Pandroid.injected.signing.store.password=${keyStoreInfo.keystorePassword || ''}`,
            `-Pandroid.injected.signing.key.alias=${keyStoreInfo.keystoreAlias || ''}`,
            `-Pandroid.injected.signing.key.password=${keyStoreInfo.keystoreAliasPassword || ''}`);
        console.log('执行命令:', gradleCmd, gradleArgs.join(' '));

        const gradleProcess = spawn(gradleCmd, gradleArgs, {
            cwd: this._androidDir,
            stdio: 'pipe',
            shell: true,
            windowsVerbatimArguments: true
        });

        // 使用 Buffer 处理 stdout
        gradleProcess.stdout.on('data', (data: Buffer) => {
            let output = '';
            try {
                // 尝试用 GBK 解码
                output = iconv.decode(Buffer.from(data), 'gbk').trim();
                // 如果出现乱码，尝试用 UTF-8 解码
                if (output.includes('')) {
                    output = data.toString('utf8').trim();
                }
            } catch (e) {
                // 如果解码失败，使用默认 UTF-8
                output = data.toString('utf8').trim();
            }

            if (output && !output.includes('Picked up JAVA_TOOL_OPTIONS')) {
                console.log(`Gradle ${taskName}: ${output}`);
            }
        });

        // 使用 Buffer 处理 stderr
        gradleProcess.stderr.on('data', (data: Buffer) => {
            let error = '';
            try {
                // 尝试用 GBK 解码
                error = iconv.decode(Buffer.from(data), 'gbk').trim();
                // 如果出现乱码，尝试用 UTF-8 解码
                if (error.includes('')) {
                    error = data.toString('utf8').trim();
                }
            } catch (e) {
                // 如果解码失败，使用默认 UTF-8
                error = data.toString('utf8').trim();
            }
            console.error(`Gradle ${taskName} 错误: ${error}`);
        });

        return new Promise<void>((resolve, reject) => {
            gradleProcess.on('error', (error) => {
                console.error(`Gradle ${taskName} 进程错误:`, error);
                reject(error);
            });
            gradleProcess.on('close', (code) => {
                if (code === 0) {
                    console.log(`Gradle ${taskName} 完成`);
                    resolve();
                    super.afterBuildFinish();
                } else {
                    reject(new Error(`Gradle ${taskName} 失败，退出码: ${code}`));
                }
            });
        });
    }

    //将构建目录下的远程资源上传(最好先在打包机上打包一次，提前发现问题)
    // public async afterBuildFinish() {
    //     let channelInfo: ChannelInfo = this.configData.platforms[this.curPackChannel];
    //     let cdnrespath = channelInfo.remoteDir;

    //     if (!cdnrespath) {
    //         console.log('No CDN path specified, skipping CDN operations');
    //         return;
    //     }

    //     console.log('CDN operations starting for path:', cdnrespath);

    //     try {
    //         console.log('upload cdn res start');
    //         try {
    //             PackUtil.pullCDNRes(cdnrespath);
    //         } catch (error) {
    //             console.error('Error during CDN pull:', error);
    //         }

    //         try {
    //             PackUtil.uploadCDNRes(cdnrespath);
    //         } catch (error) {
    //             console.error('Error during CDN upload:', error);
    //         }
    //         console.log('upload cdn res finish');
    //     } catch (error) {
    //         console.error('Error in CDN operations:', error);
    //     }
    // }

    private async logGradleConfig(): Promise<void> {
        console.log("***********************检查参数***************************");
        // 检查 local.properties
        const localPropertiesPath = path.join(this._androidDir, 'local.properties');
        if (fs.existsSync(localPropertiesPath)) {
            const content = fs.readFileSync(localPropertiesPath, 'utf8');
            console.log('local.properties 的内容:', content);
        }

        // 检查 build.gradle 中的 AGP 版本
        const buildGradlePath = path.join(this._androidDir, 'build.gradle');
        if (fs.existsSync(buildGradlePath)) {
            const content = fs.readFileSync(buildGradlePath, 'utf8');
            const agpVersion = content.match(/com\.android\.tools\.build:gradle:(.+)'/)?.[1];
            console.log('Android Gradle Plugin Version:', agpVersion || 'Not found');
        }

        // 从 gradle-wrapper.properties 获取 Gradle 版本
        const wrapperPropertiesPath = path.join(this._androidDir, 'gradle/wrapper/gradle-wrapper.properties');
        if (fs.existsSync(wrapperPropertiesPath)) {
            const content = fs.readFileSync(wrapperPropertiesPath, 'utf8');
            const gradleVersion = content.match(/gradle-(.+)-bin/)?.[1];
            console.log('Gradle Version:', gradleVersion || 'Not found');
        }

        // 检查 build.gradle 中的版本信息
        const launcherBuildGradlePath = path.join(this._androidDir, 'launcher/build.gradle');
        if (fs.existsSync(launcherBuildGradlePath)) {
            const content = fs.readFileSync(launcherBuildGradlePath, 'utf8');

            // 提取 versionCode 和 versionName
            const versionCode = content.match(/versionCode\s+(\d+)/)?.[1];
            const versionName = content.match(/versionName\s*['"](.*?)['"]/)?.[1];
            console.log('Bundle Version:', versionName || 'Not found');
            console.log('Bundle Version Code:', versionCode || 'Not found');
        }

        console.log("**************************************************");
    }

}